import LangTypeEnum from '@/framework/constant/LangTypeEnum'
import SkuField from '@/framework/components/sku/SkuField'
import TypeConvertor from '@/framework/infra/type/TypeConvertor'
import LangText from '@/framework/components/lang/LangText'
import SkuFieldTypeEnum from '@/framework/components/sku/SkuFieldTypeEnum'

export default class SkuListEntity {
  constructor() {
    this.skuList = []
    this.skuPropTypeList = []
    this.isEdit = false
    this.defaultSkuIndex = 0
    this.skuFields = []
    this.skuAllPropTypeList = []
    this.fieldValueMap = {}
    this.inited = false
    this.delayExec = []
  }

  setLangOptions(langOptions) {
    this.langOptions = langOptions
  }

  get canBatchSetting () {
    return this.skuList.length > 1
  }

  get validSkuPropTypeList () {
    return this.skuPropTypeList.filter(el => el.propNameList.length)
  }

  setSkuFields (skuFields) {
    this.skuFields = skuFields
  }

  setIsEdit (isEdit) {
    this.isEdit = isEdit
    // if (this.isEdit !== isEdit) {
    //   // this.calcSkuList()
    //   // this.addDelay('reset')
    // }
  }

  batchSetValue () {
    const condMap = this.skuAllPropTypeList.filter(el => el.propTypeFlag).reduce((r, a) => {
      r[a.title] = a.value
      return r
    }, {})
    const addFlagMap = {}
    const valueMap = this.skuAllPropTypeList.filter(el => !el.propTypeFlag && el.value).reduce((r, a) => {
      r[a.name] = a.value
      if ('addFlag' in a) {
        addFlagMap[a.name] = a.addFlag
      }
      return r
    }, {})
    this.skuList.filter(skuFieldList => {
      return !skuFieldList.filter(el => el.propTypeFlag)
        .some(el => condMap[el.title] !== '' && condMap[el.title] !== el.value)
    }).forEach(skuFieldList => {
      Object.keys(valueMap).forEach(key => {
        const item = skuFieldList.find(el => !el.propTypeFlag && el.name === key)
        if (item) {
          item.value = valueMap[key]
          if (item.name in addFlagMap) {
            item.addFlag = addFlagMap[item.name]
          }
        }
      })
    })
  }

  get currentModeSkuFields () {
    return this.skuFields.filter(item => {
      return (item.isDisplayEditMode && this.isEdit) || (item.isDisplayAddMode && !this.isEdit)
    })
  }

  getValidateErrorMsg () {
    let rt = ''
    if (this.langOptions) {
      this.validSkuPropTypeList.every(({ propType, propNameList }) => {
        const langShowMap = {}
        return propNameList.every(({ name, langText }) => {
          const lang = langText.getFirstEmptyLang()
          if (lang) {
            rt = `商品规格类型${propType}=>${name}的${lang.name}不能为空`
            return false
          }
          return LangTypeEnum.getValues().every(lang => {
            langShowMap[lang.id] = langShowMap[lang.id] || {}
            if (langShowMap[lang.id][langText[lang.id]]) {
              rt = `商品规格类型${propType}=>${name}的${lang.name}=>${langText[lang.id]}重复了`
              return false
            }
            langShowMap[lang.id][langText[lang.id]] = true
            return true
          })
        })
      })
    }
    if (!rt) {
      this.skuList.every((skuFieldList, idx) => {
        return skuFieldList.every(skuField => {
          if (skuField.required && !skuField.isDefaultSkuField) {
            if (typeof skuField.value !== 'number' && (!skuField.value || skuField.value.toString().trim().length === 0)) {
              rt = `第${idx + 1}行${skuField.title}不能为空`
              return false
            }
          }
          return true
        })
      })
    }
    return rt
  }

  calcSkuAllPropTypeList () {
    this.skuAllPropTypeList = this.validSkuPropTypeList.map(el => new SkuField({
      title: el.propType,
      required: false,
      propTypeFlag: true,
      options: [{
        label: '全部' + el.propType,
        value: ''
      }].concat(el.propNameList.map(el => ({
        value: el.name,
        label: el.name
      }))),
      value: ''
    })).concat(this.currentModeSkuFields.map(el => el.clone()))
  }

  reset () {
    if (!this.inited) {
      // 没有初始话，延迟执行
      this.addDelay('reset')
      return
    }
    this.fieldValueMap = {}
    this.skuPropTypeList = []
    this.calcSkuList()
  }

  init () {
    this.calcSkuAllPropTypeList()
    this.inited = true
    // 已加载
    this.invokeDelayExec()
  }

  invokeDelayExec () {
    for (const delayExecElement of this.delayExec) {
      this[delayExecElement.name](delayExecElement.param)
    }
    this.delayExec = []
  }

  addDelay (name, param) {
    // if (this.delayExec.some(el => el.name === name)) {
    //   return
    // }
    this.delayExec = [{
      name,
      param
    }]
    // this.delayExec.push({
    //   name,
    //   param
    // })
  }

  setValue (value) {
    if (!this.inited) {
      // 没有初始话，延迟执行
      this.addDelay('setValue', value)
      return
    }
    const skuPropTypeMap = {}
    this.fieldValueMap = {}
    value.forEach(item => {
      const skuProps = TypeConvertor.toJSON(item.skuProps) || {}
      const skuLangList = this.langOptions ? item[this.langOptions.skuUpdateField] : null
      const fieldValueMapValue = []
      Object.keys(skuProps).forEach((title, idx) => {
        let titleLangText = null
        let valueLangText = null
        if (skuLangList) {
          titleLangText = LangText.create()
          valueLangText = LangText.create()
          LangTypeEnum.getValues().forEach(lang => {
            const foundLang = skuLangList.find(el => el.languageCode === lang.id)
            if (foundLang) {
              const foundedSkuProps = TypeConvertor.toJSON(foundLang.skuProps) || {}
              const keys = Object.keys(foundedSkuProps)
              if (keys.length) {
                titleLangText[lang.id] = keys[idx]
                valueLangText[lang.id] = foundedSkuProps[titleLangText[lang.id]]
              }
            }
          })
        }
        if (!skuPropTypeMap[title]) {
          skuPropTypeMap[title] = { propType: title, propNameList: [], propName: '' }
          if (skuLangList) {
            skuPropTypeMap[title].langText = titleLangText
          }
        }
        const value = skuProps[title]
        if (!skuPropTypeMap[title].propNameList.some(el => el.name === value)) {
          const propName = {
            name: value
          }
          if (skuLangList) {
            propName.langText = valueLangText
          }
          skuPropTypeMap[title].propNameList.push(propName)
        }
        fieldValueMapValue.push(new SkuField({
          title,
          propTypeFlag: true,
          fieldType: SkuFieldTypeEnum.STATIC,
          titleLangText,
          valueLangText,
          value
        }))
      })
      const key = Object.values(skuProps).join('#')
      this.fieldValueMap[key] = fieldValueMapValue.concat(this.currentModeSkuFields.map(el => new SkuField({
        rowSpan: 1,
        ...el,
        value: el.allowAdd ? '' : item[el.name]
      })))
    })
    this.skuPropTypeList = Object.values(skuPropTypeMap)
    this.calcSkuList()
  }

  calcSkuList () {
    const customSkuPropList = this.validSkuPropTypeList
    const skuList = []
    let groupCount = 1 // 按分類種類數量分組
    const rowsCount = customSkuPropList.reduce((a, b) => a * b.propNameList.length, 1) || 1
    for (let i = 0; i < rowsCount; i++) {
      skuList.push([]) // 初始化
    }
    for (let i = 0; i < customSkuPropList.length; i++) {
      const customSkuProp = customSkuPropList[i]
      const propNameList = customSkuProp.propNameList
      const rowSpan = rowsCount / propNameList.length / groupCount
      const groupSize = rowsCount / groupCount
      for (let g = 0; g < groupCount; g++) {
        for (let j = 0; j < propNameList.length; j++) {
          for (let k = 0; k < rowSpan; k++) {
            skuList[groupSize * g + j * rowSpan + k][i] = new SkuField({
              value: propNameList[j].name, // prop
              title: customSkuProp.propType,
              propTypeFlag: true,
              fieldType: SkuFieldTypeEnum.STATIC,
              titleLangText: customSkuProp.langText,
              valueLangText: propNameList[j].langText,
              rowSpan: k === 0 ? rowSpan : 0
            })
          }
        }
      }
      groupCount *= propNameList.length
    }
    const defaultSkuPropList = this.currentModeSkuFields
    for (let i = 0; i < skuList.length; i++) { // 二维数组
      const key = skuList[i].map(el => el.value).join('#')
      const prevSku = this.fieldValueMap[key] // 一维数组
      if (prevSku) {
        // rowSpan 需要合并
        skuList[i].forEach((el, index) => {
          prevSku[index].rowSpan = el.rowSpan
        })
        skuList[i] = prevSku
      } else {
        skuList[i] = skuList[i].concat(defaultSkuPropList.map(el => new SkuField({
          rowSpan: 1,
          ...el
        })))
        this.fieldValueMap[key] = skuList[i] // 一维数组
      }
    }
    this.skuList = skuList
  }

  getValue (fieldName, formData = {}) {
    // 二维数组，转为一维数组
    const results = []
    const goodsProps = {}
    const goodsPropsLangMap = {}
    this.skuList.forEach(el => {
      const item = {
        defaultFlag: 0
      }
      const skuProps = {}
      const skuPropsLangList = []
      el.forEach(c => {
        if (c.propTypeFlag) { // sku type,自定义规格形成的字段
          const title = c.title
          skuProps[title] = c.value
          goodsProps[title] = goodsProps[title] || []
          if (this.langOptions) {
            skuPropsLangList.push({
              title: c.titleLangText,
              value: c.valueLangText
            })
            goodsPropsLangMap[title] = goodsPropsLangMap[title] || { title: c.titleLangText, values: [] }
          }
          if (!goodsProps[title].includes(c.value)) {
            goodsProps[title].push(c.value)
            if (this.langOptions) {
              goodsPropsLangMap[title].values.push(c.valueLangText)
            }
          }
        } else {
          if (c.required && !c.value) {
            return
          }
          let value
          if (c.isIntegerField || c.isIntegerIncAndDecField) {
            value = parseInt(c.value) || 0
            if (this.isEdit && c.isIntegerIncAndDecField && c.isDisplayEditMode) {
              item.addFlag = c.addFlag || 0
            }
          } else if (c.isFloatField) {
            value = parseFloat(c.value) || 0
          } else {
            value = c.value
          }
          item[c.name] = value
        }
      })
      if (Object.keys(skuProps).length > 0) {
        item.skuProps = skuProps
        if (this.langOptions) { // 语言包处理
          const langList = []
          LangTypeEnum.getValues().forEach(lang => {
            langList.push({
              languageCode: lang.id,
              skuProps: skuPropsLangList.reduce((r, a) => {
                r[a.title[lang.id]] = a.value[lang.id]
                return r
              }, {})
            })
          })
          item[this.langOptions.skuUpdateField] = langList
        }
      } else {
        item.skuProps = {}
        if (this.langOptions) { // 语言包处理
          item[this.langOptions.skuUpdateField] = LangTypeEnum.getValues().map(lang => {
            return {
              languageCode: lang.id,
              skuProps: {}
            }
          })
        }
      }
      results.push(item)
    })
    results[this.defaultSkuIndex].defaultFlag = 1
    /**
     *   skuUpdateField: 'skuLanguageList',
     goodsPropsUpdateField: 'goodsLanguageList'
     */
    const rt = {
      [fieldName]: results,
      goodsProps
    }
    if (this.langOptions) { // 语言包处理
      const updateField = this.langOptions.goodsPropsUpdateField
      rt[updateField] = LangTypeEnum.getValues().map(lang => {
        return {
          ...(formData[updateField] ? formData[updateField].find(i => i.languageCode === lang.id) : null),
          languageCode: lang.id,
          goodsProps: Object.values(goodsPropsLangMap).reduce((r, a) => {
            r[a.title[lang.id]] = a.values.map(el => el[lang.id])
            return r
          }, {})
        }
      })
    }
    return rt
  }
}
